{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import math\n",
    "from keras.models import Sequential\n",
    "from keras.layers import Dense\n",
    "from keras.datasets import mnist\n",
    "from keras.layers import Input, Dense, Reshape, Flatten, Dropout\n",
    "from keras.layers import BatchNormalization, Activation, ZeroPadding2D\n",
    "from keras.layers.advanced_activations import LeakyReLU\n",
    "from keras.models import Sequential, Model\n",
    "from keras.optimizers import Adam\n",
    "from keras.wrappers.scikit_learn import KerasClassifier\n",
    "from keras.utils import np_utils\n",
    "from sklearn.model_selection import cross_val_score\n",
    "from sklearn.model_selection import cross_val_predict\n",
    "from sklearn.model_selection import KFold\n",
    "from sklearn.preprocessing import LabelEncoder\n",
    "from sklearn.pipeline import Pipeline\n",
    "from sklearn.metrics import confusion_matrix\n",
    "from sklearn.metrics import matthews_corrcoef\n",
    "from keras.optimizers import Adam\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def build_discriminator():\n",
    "    model = Sequential()\n",
    "    model.add(Dense(41, input_dim=41, activation='relu'))  # discriminator takes 41 values from our dataset\n",
    "    model.add(Dense(30, activation='relu'))\n",
    "    model.add(Dense(15, activation='relu'))\n",
    "    model.add(Dense(1, activation='sigmoid'))  # outputs 0 to 1, 1 being read and 0 being fake\n",
    "\n",
    "    # model.summary()\n",
    "\n",
    "    attack = Input(shape=(41,))\n",
    "    validity = model(attack)\n",
    "\n",
    "    return Model(attack, validity)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def build_generator(hidden1, hidden2, hidden3):\n",
    "    model = Sequential()\n",
    "    model.add(Dense(hidden1, input_dim=41))  # arbitrarily selected 100 for our input noise vector?\n",
    "    model.add(LeakyReLU(alpha=0.2))\n",
    "    model.add(BatchNormalization(momentum=0.8))\n",
    "    model.add(Dense(hidden2))\n",
    "    model.add(LeakyReLU(alpha=0.2))\n",
    "    model.add(BatchNormalization(momentum=0.8))\n",
    "    model.add(Dense(hidden3))\n",
    "    model.add(LeakyReLU(alpha=0.2))\n",
    "    model.add(BatchNormalization(momentum=0.8))\n",
    "    model.add(Dense(41, activation='relu'))  # outputs a generated vector of the same size as our data (41)\n",
    "\n",
    "    # model.summary()\n",
    "\n",
    "    noise = Input(shape=(41,))\n",
    "    attack = model(noise)\n",
    "    return Model(noise, attack)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def trainGAN(gen_hidden1, gen_hidden2, gen_hidden3):\n",
    "    batch_size = 256\n",
    "    epochs = 7000\n",
    "    optimizer = Adam(0.0002, 0.5)\n",
    "    \n",
    "    dataframe = pd.read_csv('../../CSV/portsweep.csv').sample(500) # sample 100 data points randomly from the csv\n",
    "    \n",
    "    # apply \"le.fit_transform\" to every column (usually only works on 1 column)\n",
    "    le = LabelEncoder()\n",
    "    dataframe_encoded = dataframe.apply(le.fit_transform)\n",
    "    dataset = dataframe_encoded.values\n",
    "    \n",
    "    #to visually judge results\n",
    "    print(\"Real portsweep attacks:\")\n",
    "    print(dataset[:2])\n",
    "    \n",
    "    # Set X as our input data and Y as our label\n",
    "    X_train = dataset[:, 0:41].astype(float)\n",
    "    Y_train = dataset[:, 41]\n",
    "    \n",
    "    # labels for data. 1 for valid attacks, 0 for fake (generated) attacks\n",
    "    valid = np.ones((batch_size, 1))\n",
    "    fake = np.zeros((batch_size, 1))\n",
    "    \n",
    "    # build the discriminator portion\n",
    "    discriminator = build_discriminator();\n",
    "    \n",
    "    # we want to add our custom loss function here? look at the bookmark for implementation\n",
    "    discriminator.compile(loss='binary_crossentropy', optimizer=optimizer, metrics=['accuracy'])\n",
    "    \n",
    "    # build the generator portion\n",
    "    generator = build_generator(gen_hidden1, gen_hidden2, gen_hidden3)\n",
    "    \n",
    "    #input and output of our combined model\n",
    "    z = Input(shape=(41,))\n",
    "    attack = generator(z)\n",
    "    validity = discriminator(attack)\n",
    "    \n",
    "    # build combined model from generator and discriminator\n",
    "    combined = Model(z, validity)\n",
    "    combined.compile(loss='binary_crossentropy', optimizer=optimizer, metrics = [evaluatorLoss(estimator, attack)])\n",
    "    \n",
    "    #break condition for training (when diverging)\n",
    "    loss_increase_count = 0;\n",
    "    prev_g_loss = 0;\n",
    "    \n",
    "    for epoch in range(epochs):\n",
    "\n",
    "        # ---------------------\n",
    "        #  Train Discriminator\n",
    "        # ---------------------\n",
    "        \n",
    "        # selecting batch_size random attacks from our training data\n",
    "        idx = np.random.randint(0, X_train.shape[0], batch_size)\n",
    "        attacks = X_train[idx]\n",
    "        \n",
    "        # generate a matrix of noise vectors\n",
    "        noise = np.random.normal(0, 1, (batch_size, 41))\n",
    "        \n",
    "        # create an array of generated attacks\n",
    "        gen_attacks = generator.predict(noise)\n",
    "        \n",
    "        # loss functions, based on what metrics we specify at model compile time\n",
    "        d_loss_real = discriminator.train_on_batch(attacks, valid)\n",
    "        d_loss_fake = discriminator.train_on_batch(gen_attacks, fake)\n",
    "        d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)\n",
    "        \n",
    "        # generator loss function\n",
    "        g_loss = combined.train_on_batch(noise, valid)\n",
    "        \n",
    "        if epoch % 100 == 0:\n",
    "            print(\"%d [D loss: %f, acc.: %.2f%%] [G loss: %f] [Loss change: %.3f, Loss increases: %.0f]\" % (epoch, d_loss[0], 100 * d_loss[1], g_loss, g_loss - prev_g_loss, loss_increase_count))\n",
    "        \n",
    "        # if our generator loss icreased this iteration, increment the counter by 1\n",
    "        if (g_loss - prev_g_loss) > 0:\n",
    "            loss_increase_count = loss_increase_count + 1\n",
    "        else: \n",
    "            loss_increase_count = 0  # otherwise, reset it to 0, we are still training effectively\n",
    "            \n",
    "        prev_g_loss = g_loss\n",
    "            \n",
    "        if loss_increase_count > 5:\n",
    "            print('Stoping on iteration: ', epoch)\n",
    "            break\n",
    "            \n",
    "        if epoch % 20 == 0:\n",
    "            f = open(\"../../Results/GANresultsportsweep.txt\", \"a\")\n",
    "            np.savetxt(\"../../Results/GANresultsportsweep.txt\", gen_attacks, fmt=\"%.0f\")\n",
    "            f.close()\n",
    "            \n",
    "    # peek at our results\n",
    "    results = np.loadtxt(\"../../Results/GANresultsportsweep.txt\")\n",
    "    print(\"Generated portsweep attacks: \")\n",
    "    print(results[:2])\n",
    "        \n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "ename": "FileNotFoundError",
     "evalue": "File b'../../CSV/normalAndPortsweep.csv' does not exist",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mFileNotFoundError\u001b[0m                         Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-5-196dd151ec03>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      6\u001b[0m \u001b[0;31m# load dataset\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      7\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 8\u001b[0;31m \u001b[0mdataframe\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread_csv\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"../../CSV/normalAndPortsweep.csv\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;31m#, header=True)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      9\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     10\u001b[0m \u001b[0;31m# samples 10000 random data points from 500k\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pandas/io/parsers.py\u001b[0m in \u001b[0;36mparser_f\u001b[0;34m(filepath_or_buffer, sep, delimiter, header, names, index_col, usecols, squeeze, prefix, mangle_dupe_cols, dtype, engine, converters, true_values, false_values, skipinitialspace, skiprows, nrows, na_values, keep_default_na, na_filter, verbose, skip_blank_lines, parse_dates, infer_datetime_format, keep_date_col, date_parser, dayfirst, iterator, chunksize, compression, thousands, decimal, lineterminator, quotechar, quoting, escapechar, comment, encoding, dialect, tupleize_cols, error_bad_lines, warn_bad_lines, skipfooter, doublequote, delim_whitespace, low_memory, memory_map, float_precision)\u001b[0m\n\u001b[1;32m    676\u001b[0m                     skip_blank_lines=skip_blank_lines)\n\u001b[1;32m    677\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 678\u001b[0;31m         \u001b[0;32mreturn\u001b[0m \u001b[0m_read\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfilepath_or_buffer\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkwds\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    679\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    680\u001b[0m     \u001b[0mparser_f\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__name__\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pandas/io/parsers.py\u001b[0m in \u001b[0;36m_read\u001b[0;34m(filepath_or_buffer, kwds)\u001b[0m\n\u001b[1;32m    438\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    439\u001b[0m     \u001b[0;31m# Create the parser.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 440\u001b[0;31m     \u001b[0mparser\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mTextFileReader\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfilepath_or_buffer\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwds\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    441\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    442\u001b[0m     \u001b[0;32mif\u001b[0m \u001b[0mchunksize\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0miterator\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pandas/io/parsers.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, f, engine, **kwds)\u001b[0m\n\u001b[1;32m    785\u001b[0m             \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moptions\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'has_index_names'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mkwds\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'has_index_names'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    786\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 787\u001b[0;31m         \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_make_engine\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mengine\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    788\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    789\u001b[0m     \u001b[0;32mdef\u001b[0m \u001b[0mclose\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pandas/io/parsers.py\u001b[0m in \u001b[0;36m_make_engine\u001b[0;34m(self, engine)\u001b[0m\n\u001b[1;32m   1012\u001b[0m     \u001b[0;32mdef\u001b[0m \u001b[0m_make_engine\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mengine\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'c'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1013\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0mengine\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m'c'\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1014\u001b[0;31m             \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_engine\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mCParserWrapper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moptions\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   1015\u001b[0m         \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1016\u001b[0m             \u001b[0;32mif\u001b[0m \u001b[0mengine\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m'python'\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pandas/io/parsers.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, src, **kwds)\u001b[0m\n\u001b[1;32m   1706\u001b[0m         \u001b[0mkwds\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'usecols'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0musecols\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1707\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1708\u001b[0;31m         \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_reader\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mparsers\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mTextReader\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msrc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwds\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   1709\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1710\u001b[0m         \u001b[0mpassed_names\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnames\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32mpandas/_libs/parsers.pyx\u001b[0m in \u001b[0;36mpandas._libs.parsers.TextReader.__cinit__\u001b[0;34m()\u001b[0m\n",
      "\u001b[0;32mpandas/_libs/parsers.pyx\u001b[0m in \u001b[0;36mpandas._libs.parsers.TextReader._setup_parser_source\u001b[0;34m()\u001b[0m\n",
      "\u001b[0;31mFileNotFoundError\u001b[0m: File b'../../CSV/normalAndPortsweep.csv' does not exist"
     ]
    }
   ],
   "source": [
    "# Initialize Random Number Generator\n",
    "# fix random seed for reproducibility\n",
    "seed = 7\n",
    "np.random.seed(seed)\n",
    "\n",
    "# load dataset\n",
    "\n",
    "dataframe = pd.read_csv(\"../../CSV/normalAndPortsweep.csv\")#, header=True) \n",
    "\n",
    "# samples 10000 random data points from 500k\n",
    "dataframe = dataframe.sample(n=10000)\n",
    "# LabelEncoder, turns all our categorical data into integers\n",
    "le = LabelEncoder()\n",
    "\n",
    "# apply \"le.fit_transform\" to every column (usually only works on 1 column)\n",
    "dataframe_encoded = dataframe.apply(le.fit_transform)\n",
    "attack_labels = le.classes_\n",
    "indices_of_portsweep = np.where(attack_labels == 'portsweep.')\n",
    "portsweep_index = indices_of_portsweep[0]\n",
    "dataset = dataframe_encoded.values\n",
    "\n",
    "print(attack_labels)\n",
    "print(portsweep_index)\n",
    "\n",
    "#Set X as our input data and Y as our label\n",
    "X = dataset[:,0:41].astype(float)\n",
    "Y = dataset[:,41]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# encode class values as integers\n",
    "encoder = LabelEncoder()\n",
    "encoder.fit(Y)\n",
    "encoded_Y = encoder.transform(Y)\n",
    "# convert integers to dummy variables (i.e. one hot encoded)\n",
    "dummy_y = np_utils.to_categorical(encoded_Y)\n",
    "# print(dummy_y)\n",
    "#print(len(dummy_y[0]))\n",
    "num_of_classes = len(dummy_y[0])  # the length of dummy y is the number of classes we have in our small sample\n",
    "# since we are randomly sampling from a large dataset, we might not get 1 of every class in our sample\n",
    "# we need to set output layer to be equal to the length of our dummy_y vectors\n",
    "print(num_of_classes)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# define baseline model\n",
    "def baseline_model():\n",
    "    # create model\n",
    "    model = Sequential()\n",
    "    \n",
    "    inputs = 41\n",
    "    hidden_layer1 = 10\n",
    "    hidden_layer2 = 5\n",
    "    hidden_layer3 = 0\n",
    "    outputs = num_of_classes  #needs to be this variable in case we forget to sample. Could end up having 10 classes or 12, etc\n",
    "    \n",
    "    model.add(Dense(hidden_layer1, input_dim=inputs, activation='relu'))\n",
    "    if hidden_layer2 != 0:\n",
    "        model.add(Dense(hidden_layer2, activation='relu'))\n",
    "    if hidden_layer3 != 0:\n",
    "        model.add(Dense(hidden_layer3, activation='relu'))\n",
    "    model.add(Dense(outputs, activation='softmax'))\n",
    "    \n",
    "    # Compile model\n",
    "    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) #optimizer=adam\n",
    "    return model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#for i in range(0,10):\n",
    "estimator = KerasClassifier(build_fn=baseline_model, epochs=32, batch_size=200, verbose=2)\n",
    "\n",
    "kfold = KFold(n_splits=10, shuffle=True, random_state=seed)\n",
    "y_pred = cross_val_predict(estimator, X, dummy_y, cv=kfold)\n",
    "results = cross_val_score(estimator, X, dummy_y, cv=kfold)\n",
    "\n",
    "trained_classifier = estimator.fit(X, Y)\n",
    "print(type(estimator))\n",
    "\n",
    "cm = confusion_matrix(Y, y_pred)\n",
    "print(cm)\n",
    "print(\"total: \" + str(cm.sum()))\n",
    "print(\"accuracy: \" + str(np.trace(cm) / cm.sum()))\n",
    "print(\"Matthews correlation coefficient: \" + str(matthews_corrcoef(Y, y_pred)))\n",
    "\n",
    "\n",
    "\n",
    "print(\"Baseline: %.2f%% (%.2f%%)\" % (results.mean()*100, results.std()*100))\n",
    "\n",
    "f = open(\"../../Results/discriminatorResults.txt\", \"a+\")\n",
    "f.write(\"TP: %d, FP: %d, FN: %d, TN: %d\\n\" % (cm[0][0], cm[0][1], cm[1][0], cm[1][1]))\n",
    "f.close()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def evaluatorLoss(estimator, generatedData):\n",
    "    ypred = estimator.predict(generatedData)\n",
    "    def evaluatorLossMetric(portsweep_labels, ypred):\n",
    "        cm = confusion_matrix(portsweep_labels, ypred)\n",
    "        accuracy = np.trace(cm) / cm.sum()\n",
    "        return 1 - accuracy\n",
    "    return evaluatorLossMetric"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\"\"\"\n",
    "f = open(\"GeneratorHypersAbove50percentAccuracy.txt\", \"w\")\n",
    "f.write(\"\"\"\"\"\" Hidden layer counts for Generator model that resulted in over 50% generated attacks labeled correctly:\n",
    "    ------------------------------------------------------------------------------------------------\n",
    "    \"\"\"\"\"\")\n",
    "f.close()\n",
    "\"\"\"\n",
    "\n",
    "while(1):\n",
    "    # generate random numbers for the hidden layer sizes of our generator\n",
    "    gen_hidden1 =  np.random.randint(1, 101)\n",
    "    gen_hidden2 =  np.random.randint(1, 101)\n",
    "    gen_hidden3 =  np.random.randint(1, 101)\n",
    "    \n",
    "    i = 0\n",
    "    \n",
    "    \n",
    "    # train 5 times on each setup, in case we get unlucky initalization on an otherwise good setup\n",
    "    while i < 100:\n",
    "        # create a unique filename in case we want to store the results (good accuracy)\n",
    "        result_filename = \"../../Results/GANresultsportsweep%.0f%.0f%.0fiter%.0ftry2.txt\" % (gen_hidden1, gen_hidden2, gen_hidden3, i)\n",
    "\n",
    "        trainGAN(gen_hidden1, gen_hidden2, gen_hidden3)\n",
    "        \n",
    "        # load generate attacks from file\n",
    "        results = np.loadtxt(\"../../Results/GANresultsportsweep.txt\")\n",
    "\n",
    "        # predict attack lables (as encoded integers)\n",
    "        y_pred = estimator.predict(results)\n",
    "        print(y_pred)\n",
    "\n",
    "        # create appropriate labels for our generated portsweep attacks\n",
    "        portsweep_labels = np.full((len(results),), portsweep_index[0])\n",
    "\n",
    "        # convert integer labels back to string, get all unique strings and their count\n",
    "        predicted_as_label = attack_labels[y_pred]\n",
    "        unique_labels = np.unique(predicted_as_label)\n",
    "\n",
    "        for label in unique_labels:\n",
    "            print(\"Attack type: %s     number predicted:  %.0f\" % (label, len(np.where(predicted_as_label == label)[0])))\n",
    "    \n",
    "        print()\n",
    "        # create a confusion matrix of the results\n",
    "        cm = confusion_matrix(portsweep_labels, y_pred)\n",
    "        \n",
    "        accuracy = np.trace(cm) / cm.sum()\n",
    "        print(cm)\n",
    "        print(\"total: \" + str(cm.sum()))\n",
    "        print(\"accuracy: \" + str(accuracy))\n",
    "        \n",
    "        if accuracy > .50:\n",
    "            f = open(\"../../Results/GeneratorHypersAbove50percentAccuracyportsweep.txt\", \"a\")\n",
    "            f.write(\"\"\"\n",
    "            \n",
    "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
    "Accuracy: %.3f\n",
    "Generator hidden layer 1 size: %.0f\n",
    "Generator hidden layer 2 size: %.0f\n",
    "Generator hidden layer 3 size: %.0f\n",
    "Iteration %.0f\n",
    "Result file name: %s\n",
    "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\"\"\" % (accuracy, gen_hidden1, gen_hidden2, gen_hidden3, i, result_filename))\n",
    "            f.close()\n",
    "            result_filename = \"../../Results/\" + result_filename\n",
    "            \n",
    "            f = open(result_filename, \"w\")\n",
    "            f.close()\n",
    "            np.savetxt(result_filename, results, fmt=\"%.0f\")\n",
    "        \n",
    "        i = i + 1\n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
